var utils = require("js/utils");
var gamejs = require("gamejs");
var GameEntity = require("js/gameEntity").GameEntity;

qModule("js/utils");

test("utils.collideGeneric(geA, geB)", function () {
	// the checks for collision between entity with the same shape is
	// done with the collideCircle and collideRect methods of gamejs.sprite
	// test only the collision between different shapes(rect and circle)
	var upgList = [{image : IMAGE_ROOT + "radar.png"}];
	var rect = new GameEntity(null, [100, 100], upgList, null, null, SHAPE_RECTANGULAR);
	var circle = new GameEntity(null, [100, 100], upgList, null, null);
	
	// define a new rect and radius to avoid surprises from image
	var circleRect = new gamejs.Rect([90, 90], [20, 20]);
	circle.rect = circleRect;
	circle.radius = 10;
	
	// test without collision
	var testRect = new gamejs.Rect([10, 10], [70, 70]);
	rect.rect = testRect;
	ok( ! utils.collideGeneric(rect, circle),"Test without collision(rect, circle)");
	ok( ! utils.collideGeneric(circle, rect),"Test without collision(circle, rect)")
	
	// test with intersection
	testRect = new gamejs.Rect([55, 105], [200, 50]);
	rect.rect = testRect;
	ok(utils.collideGeneric(rect, circle),"Test with intersection(rect, circle)");
	ok(utils.collideGeneric(circle, rect),"Test with intersection(circle, rect)")
	
	// test with tangent
	testRect = new gamejs.Rect([110, 80], [10, 50]);
	rect.rect = testRect;
	ok(utils.collideGeneric(rect, circle),"Test with tangent(rect, circle)");
	ok(utils.collideGeneric(circle, rect),"Test with tangent(circle, rect)")
	
	// test in the corner, no collision
	testRect = new gamejs.Rect([80, 80], [10, 10]);
	rect.rect = testRect;
	ok( ! utils.collideGeneric(rect, circle),
		"Test in corner, no collision(rect, circle)");
	ok( ! utils.collideGeneric(circle, rect),
		"Test in corner, no collision(circle, rect)");
	
	// test in the corner, tangent
	testRect = new gamejs.Rect([107, 90], [30, 3]);
	rect.rect = testRect;
	ok(utils.collideGeneric(rect, circle),
		"Test in corner, tangent(rect, circle)");
	ok(utils.collideGeneric(circle, rect),
		"Test in corner, tangent(circle, rect)");
});

test("utils.validIndex(index, array)", function () {
	var array0 = [];
	var array1 = ["test"];
	var array2 = [true, 0];
	var array3 = [12, "test", {vero : true}];
	var string4 = "test";
	
	// Tests with some valid indexes
	ok(utils.validIndex(0, array1), "Test index = 0 and array.length = 1");
	ok(utils.validIndex(0, array2), "Test index = 0 and array.length = 2");
	ok(utils.validIndex(2, array3), "Test index = 2 and array.length = 3");
	ok(utils.validIndex(2, string4), "Test index = 2 and array = 'test'");
	ok(utils.validIndex(3, string4), "Test index = 3 and array = 'test'");
	
	// Tests with some invalid indexes
	ok( ! utils.validIndex(0, array0), "Test index = 0 and array.length = 0");
	ok( ! utils.validIndex(1, array1), "Test index = 1 and array.length = 1");
	ok( ! utils.validIndex(-1, array2), "Test index = -1 and array.length = 2");
	ok( ! utils.validIndex(3, array3), "Test index = 3 and array.length = 3");
	ok( ! utils.validIndex(4, string4), "Test index = 4 and array = 'test'");
});

test("utils.areCoordinates(obj)", function () {
	// Tests with some objects that aren't coordinates
	ok( ! utils.areCoordinates([1, ""]), "Test with argument = [1, '']");
	ok( ! utils.areCoordinates([, 1]), "Test with argument = [undefined, 1]");
	ok( ! utils.areCoordinates([NaN, 1]), "Test with argument = [NaN, 1]");
	ok( ! utils.areCoordinates([1]), "Test with argument = [1]");
	ok( ! utils.areCoordinates([1, 0, 3]), "Test with argument = [1, 0, 3]");
	ok( ! utils.areCoordinates(1), "Test with argument = 1");
	ok( ! utils.areCoordinates("1, 2"), "Test with argument = '1, 2'");
	
	// Tests with some objects that are coordinates
	ok(utils.areCoordinates([1, 0]), "Test with argument = [1, 0]");
	ok(utils.areCoordinates([-12, 15]), "Test with argument = [-12, 15]");
	ok(utils.areCoordinates([0, 1500]), "Test with argument = [0, 1500]");
});

test("utils.calcTopleft(center, dims)", function () {
	var center = [10, 10];
	var dims = [10, 10];
	deepEqual(utils.calcTopleft(center, dims), [5, 5],
		"Test center = [10, 10] and dims = [10, 10])"
	);

	center = [10, 10];
	dims = [0, 0];
	deepEqual(utils.calcTopleft(center, dims), [10, 10],
		"Test center = [10, 10] and dims = [0, 0])"
	);
	
	center = [0, 0];
	dims = [10, 20];
	deepEqual(utils.calcTopleft(center, dims), [-5, -10],
		"Test center = [0, 0] and dims = [10, 20])"
	);
	
	center = [100, 100];
	dims = [55, 55];
	deepEqual(utils.calcTopleft(center, dims), [73, 73],
		"Test center = [100, 100] and dims = [55, 55])"
	);
});

test("utils.distance()", function () {
	// Test with the formula
	var pointAx = 2, pointAy = 2;
	var pointBx = 5, pointBy = 6;
	var pointA = [pointAx, pointAy];
	var pointB = [pointBx, pointBy];
	var distance = Math.sqrt(
		Math.pow(pointAx - pointBx, 2) + Math.pow(pointAy - pointBy, 2)
	);
	strictEqual(utils.distance(pointA, pointB), distance,
		"Test with arguments: (pointA = [2,2], pointB = [5,6])"
	);
	// Test with positive numbers
	pointA = [1, 1];
	pointB = [4, 5];
	strictEqual(utils.distance(pointA, pointB), 5,
		"Test with arguments: (pointA = [1,1], pointB = [4,5])"
	);
	// Test with negative numbers
	pointA = [-1, -1];
	pointB = [-4, -5];
	strictEqual(utils.distance(pointA, pointB), 5,
		"Test with arguments: (pointA = [-1,-1], pointB = [-4,-5])"
	);
	// Test with zeros
	pointA = [0, 0];
	pointB = [0, 0];
	strictEqual(utils.distance(pointA, pointB), 0,
		"Test with arguments: (pointA = [0,0], pointB = [0,0])"
	);
	// Test with zeros and posite numbers
	pointA = [0, 0];
	pointB = [4, 3];
	strictEqual(utils.distance(pointA, pointB), 5,
		"Test with arguments: (pointA = [0,0], pointB = [4,3])"
	);
	// Test with zeros and negative numbers
	pointA = [0, 0];
	pointB = [-4, -3];
	strictEqual(utils.distance(pointA, pointB), 5,
		"Test with arguments: (pointA = [0,0], pointB = [-4,-3])"
	);
	// Tests with positive and negative numbers
	pointA = [-1, -1];
	pointB = [3, 2];
	strictEqual(utils.distance(pointA, pointB), 5,
		"Test with arguments: (pointA = [-1,-1], pointB = [3,2])"
	);
	pointA = [-1, 1];
	pointB = [3, 4];
	strictEqual(utils.distance(pointA, pointB), 5,
		"Test with arguments: (pointA = [-1,1], pointB = [3,4])"
	);
});